package ast

import (
	"fmt"
	"path/filepath"
	"strings"

	"gitee.com/u-language/u-language/ucom/astdata"
	"gitee.com/u-language/u-language/ucom/enum"
	"gitee.com/u-language/u-language/ucom/errcode"
	"gitee.com/u-language/u-language/ucom/internal/errutil"
	"gitee.com/u-language/u-language/ucom/internal/utils"
	"gitee.com/u-language/u-language/ucom/lex"
)

// 有测试依赖函数体外的非声明语句，设置为true可以恢复之前的行为
// 缩写 Non declarative statements outside of a function 缩写成NdSotf
var NdSotfOn = false

// 缩写 The first line does not have a package declaration 缩写成FirstLineNoPackageDecl
// 控制是否允许第一行没有包声明
var FirstLineNoPackageDeclOn = false

// ParserNode 解析几行已经完成词法分析的代码，并返回自动生成的节点
//   - tree是抽象语法树, Tree.LVarTable Tree.Sbt 不能为空
//   - lines是词法分析结果
//   - sbt是被使用的符号表
//   - index是被解析开始行偏移量
//   - end是被结束开始行偏移量
//   - ret是结果保存切片，为nil将自动分配一个长度为len(lines)的
//   - IsFunc是被解析结果是否在函数内
//   - Thread控制是否并发
//
// 对同一个 [Tree] 同时调用 [ParserNode] 有数据竞争可能
func ParserNode(tree *Tree, lines []lex.Line, sbt *Sbt, state ParserNodeState) []Node {
	vlen := len(lines)
	//首先解析第一行是不是包声明，以保证接下来肯定知道抽象语法树被声明属于那个包
	if state.Index == 0 && !state.IsRecursion { //如果是第一行且非递归
		if len(lines[0].Value) != 0 {
			if lines[0].Value[0].TYPE == lex.Package { //如果第一行是包声明
				parser_package(tree, &lines[0])
				state.Index = 1
			} else { //如果第一行不是包声明
				if !FirstLineNoPackageDeclOn {
					tree.Panic(&lines[0], nil, errcode.PackageDeclMustFirstLine)
				}
			}
		} else { //如果第一行不是包声明
			if !FirstLineNoPackageDeclOn {
				tree.Panic(&lines[0], nil, errcode.PackageDeclMustFirstLine)
			}
		}
	}
	if state.Ret == nil {
		state.Ret = make([]Node, vlen)
	}
	if state.End == 0 {
		state.End = vlen
	}
	for i := state.Index; i < state.End; i++ {
		if lines[i].Value == nil || len(lines[i].Value) == 0 { //是空行
			continue
		}
		switch lines[i].Value[0].TYPE {
		case lex.VAR: //是变量声明
			ret := ParserVAR(tree, &lines[i], state.FuncInfo, sbt, state.InAutoFree)
			if state.FuncInfo == nil {
				tree.CHeaderFile.Add(CHeaderFile{ret, lines[i].Linenum})
			}
			state.Ret[i] = ret
		case lex.FUNC: //是函数声明
			autoCodeBlock(tree, enum.Func, &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.NAME, lex.Deref, lex.LEA, lex.MoreThanJustTokensWithBrackts:
			if state.FuncInfo == nil && !NdSotfOn { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			state.Ret[i] = parserSece(tree, &lines[i], state.InAutoFree, state.FuncInfo)
		case lex.IF:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			autoCodeBlock(tree, "if", &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.ELSE:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			autoCodeBlock(tree, "else", &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.FOR:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			autoCodeBlock(tree, "for", &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.RBRACE: //是右大括号
			state.Ret[i] = NewRbraceNode()
		case lex.MLCStart: //是多行注释开头
			for i < vlen-1 { //遍历lines后边的
				i++
				//直到发现多行注释结束,多行注释之间一并处理
				if len(lines[i].Value) != 0 && lines[i].Value[0].TYPE == lex.MLCEnd {
					break
				}
			}
		case lex.Return:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			state.Ret[i] = parserReturn(tree, &lines[i], state.InAutoFree, state.FuncInfo)
		case lex.GOTO:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			state.Ret[i] = parserGoto(tree, &lines[i])
		case lex.Break:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			state.Ret[i] = parserBreak(tree, &lines[i])
		case lex.Continue:
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			state.Ret[i] = parserContinue(tree, &lines[i])
		case lex.Const: //是常量声明
			ret := parserConst(tree, &lines[i], sbt, state.InAutoFree, state.FuncInfo)
			if state.FuncInfo == nil {
				tree.CHeaderFile.Add(CHeaderFile{ret, lines[i].Linenum})
			}
			state.Ret[i] = ret
		case lex.Struct: //是结构体声明
			old := i
			ret := parserStruct(tree, &i, lines, sbt, state.FuncInfo)
			if state.FuncInfo == nil {
				tree.CHeaderFile.Add(CHeaderFile{ret, lines[i].Linenum})
			}
			state.Ret[old] = ret
		case lex.Package: //是包声明
			parser_package(tree, &lines[i])
		case lex.Switch: //是switch语句
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			autoCodeBlock(tree, enum.Switch, &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.Case: //是case语句
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			old := i
			cn := parserCase(tree, &lines[old], sbt, state.InAutoFree, state.FuncInfo)
			if cn == nil {
				continue
			}
			state.Ret[old] = cn
			parserCaseOrDefaultBlock(tree, lines, &i, old, vlen, cn.Sbt, errcode.CaseErr, state)
			cn.Left, cn.Right = old, i
			i-- //当前的偏移量位于右大括号或case
		case lex.Default: //是default语句
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			old := i
			dn := parserDefault(tree, &lines[old], sbt)
			if dn == nil {
				continue
			}
			state.Ret[old] = dn
			parserCaseOrDefaultBlock(tree, lines, &i, old, vlen, dn.Sbt, errcode.DefaultErr, state)
			dn.Left, dn.Right = old, i
			i-- //当前的偏移量位于右大括号或default
		case lex.Method: //是方法声明
			autoCodeBlock(tree, enum.Method, &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.AutoFree: //是自动释放块
			if state.FuncInfo == nil { //是函数体外的非声明语句
				tree.Panic(&lines[i], nil, errcode.NdSotf)
				continue
			}
			autoCodeBlock(tree, enum.AutoFree, &i, vlen, lines, state.Ret, sbt, state.FuncInfo, state.InAutoFree)
		case lex.Import: //是import
			parserImport(tree, lines, &i, state.FuncInfo)
		case lex.Enum: //是枚举
			old := i
			ret := parserEnum(tree, &i, lines, sbt)
			if state.FuncInfo == nil {
				tree.CHeaderFile.Add(CHeaderFile{ret, lines[i].Linenum})
				continue
			}
			state.Ret[old] = ret
		default: //无法识别
			parserSece(tree, &lines[i], state.InAutoFree, state.FuncInfo)
		}
	}
	if tree != nil && state.FuncInfo == nil {
		tree.Nodes = state.Ret
		if tree.PackageName != "" {
			tree.overwrite_ident()
		}
	}
	return state.Ret
}

// ParserNodeState 是 [ParserNode] 的可选参数
type ParserNodeState struct {
	//解析结果的保存切片，如果为nil,[ParserNode]会自动创建一个
	Ret []Node
	//被解析的词法分析结果开头偏移量
	Index int
	//被解析的词法分析结果结尾偏移量（解析时这个偏移量的词法分析结果不会被处理）
	End int
	//是否在解析函数内,如果是，函数信息
	FuncInfo *FuncInfo
	//is recursion 是否递归
	IsRecursion bool
	//是否在自动释放块
	InAutoFree bool
}

// 解析变量
// 实现假定 line[0].Value[0].TYPE==VAR
func ParserVAR(t *Tree, line *lex.Line, FuncInfo *FuncInfo, sbt *Sbt, InAutoFree bool) *VarNode {
	llen := len(line.Value)
	if llen < 2 { //只有变量标识符
		t.Panic(line, nil, errcode.VARErr, errcode.NoName)
		return nil
	}
	if llen == 2 { //没有类型
		t.Panic(line, nil, errcode.VARErr, errcode.NoType)
		return nil
	}
	if llen == 3 && line.Value[1].TYPE == lex.NAME && check_is_type_token(line.Value[2].TYPE) { //声明但未初始化变量
		return checkVarNameAndType(t, line, line.Value[1].Value, &line.Value[2], sbt, FuncInfo)
	} else if llen >= 5 && line.Value[1].TYPE == lex.NAME && check_is_type_token(line.Value[2].TYPE) && line.Value[3].TYPE == lex.ASSIGN { //声明但初始化变量
		ret := checkVarNameAndType(t, line, line.Value[1].Value, &line.Value[2], sbt, FuncInfo)
		if ret == nil {
			return nil
		}
		ret.IsFunc = FuncInfo != nil
		// dest =(*line).Value[1]
		// src =(*line).Value[3:]
		expr := lex.NewLine(line.Linenum, append(append([]lex.Token(nil), (*line).Value[1]), (*line).Value[3:]...))
		asnode := parserASSIGN(t, &expr, InAutoFree, FuncInfo) //解析赋值
		if asnode == nil {                                     //如果初始化赋值不符合语法
			return nil
		}
		ret.Value = asnode.Src //变量节点记录源操作数
		if t.PackageName != "" {
			overwrite_ident_node(t, asnode)
		}
		if FuncInfo == nil { //不在函数内的赋值，就是全局变量初始化
			t.VarInitTable_File.Add(ASSIGNInfo{Ptr: asnode, LineNum: line.Linenum})
		}
		return ret
	} else { //无法识别
		t.Panic(line, nil, errcode.VARErr, errcode.OPbug)
	}
	return nil
}

// checkVarNameAndType 检查变量的名字和类型,检查通过记录的符号表
func checkVarNameAndType(t *Tree, line *lex.Line, varname string, typename *lex.Token, sbt *Sbt, FuncInfo *FuncInfo) *VarNode {
	if t.PackageName != "" {
		varname = utils.GeneratePackageSymbol(t.PackageName, varname)
	}
	var typ = parserTypeName(t, line, typename, errcode.VARErr, FuncInfo)
	if g, ok := typ.(*GenericInstantiation); ok && !utils.IsNil(g) { //记录泛型实例化
		if FuncInfo == nil || (FuncInfo != nil && isHaveType(FuncInfo.TypeParame, g.ActualType, FuncInfo.TypeParame)) {
			t.GenericTable.AddGenInst(g)
		}
	}
	code := check_name(varname) //检查名字
	if code != errcode.NoErr {
		t.Panic(line, nil, errcode.VARErr, code)
		return nil
	}
	if strings.HasPrefix(varname, enum.Generate) { //如果开头是generate
		t.Panic(line, nil, errcode.VARErr, errcode.NameCannotStartWithGenerate)
		return nil
	}
	n := NewVarNode(varname, typ, FuncInfo != nil, t.Filename, line.Linenum)
	code = sbt.add(n.Name, enum.SymbolNoParameVar, n) //符号表记录
	if code != errcode.NoErr {                        //如果变量重名
		info := sbt.Have(varname)
		var FileName string
		var LineNum int
		if v, ok := info.Info.(VarInfoSbt); ok {
			FileName = v.FileName
		} else {
			FileName = info.Info.(*VarNode).FileName
		}
		if v, ok := info.Info.(VarInfoSbt); ok {
			LineNum = v.LineNum
		} else {
			LineNum = info.Info.(*VarNode).LineNum
		}
		t.Panic(line, errcode.NewMsgSymbolRepeat(varname, FileName, t.Filename, LineNum, line.Linenum), errcode.VARErr, code)
		return nil
	}
	return n
}

// checkConstNameAndType 检查常量的名字和类型,检查通过记录的符号表
func checkConstNameAndType(t *Tree, line *lex.Line, constname string, typename *lex.Token, sbt *Sbt, FuncInfo *FuncInfo) *ConstNode {
	constname = utils.GeneratePackageSymbol(t.PackageName, constname)
	code := check_name(constname)
	if code != errcode.NoErr {
		t.Panic(line, nil, errcode.ConstErr, code)
		return nil
	}
	if strings.HasPrefix(constname, enum.Generate) { //如果开头是generate
		t.Panic(line, nil, errcode.ConstErr, errcode.NameCannotStartWithGenerate)
		return nil
	}
	typ := parserTypeName(t, line, typename, errcode.ConstErr, FuncInfo)
	ret := NewConstNode(constname, typ)
	code = sbt.AddConst(ret)   //符号表记录
	if code != errcode.NoErr { //如果常量重名
		t.Panic(line, errcode.NewMsgSymbol(constname), errcode.ConstErr, code)
		return nil
	}
	return ret
}

// parserContinuityTypeOrGenericInstantiation 解析连续类型或泛型实例化
// 假设 tk.TYPE=MoreThanJustTokensWithBrackts
func parserContinuityTypeOrGenericInstantiation(t *Tree, tk *lex.Token, line *lex.Line, err errcode.ErrCode, FuncInfo *FuncInfo) astdata.Typ {
	tks := *tk.PtrMoreThanJustTokensWithBracktsS().Ptr
	var typ astdata.Typ
	if len(tks) == 2 && tks[0].TYPE == lex.TokenWithBrackets && (tks[1].TYPE == lex.NAME || tks[1].TYPE == lex.LEA) { //如果是 []T 或 [expr]T
		typ = parserTypeName(t, line, &tks[1], err, FuncInfo)
		if typ == nil {
			return nil
		}
		token := lex_scan(t, ret_middle_str(tks[0].Value), line)
		expr := parserExprNode(t, lex.NewLine(line.Linenum, token), err, false, FuncInfo)
		if expr == nil {
			return nil
		}
		return NewContinuityType(expr, typ, tks[0].Value+tks[1].Value)
	} else if len(tks) == 2 && tks[0].TYPE == lex.TokenWithBrackets && tks[1].TYPE == lex.MoreThanJustTokensWithBrackts { //如果是 多维数组
		typ = parserContinuityTypeOrGenericInstantiation(t, &tks[1], line, err, FuncInfo)
		if typ == nil {
			return nil
		}
		token := lex_scan(t, ret_middle_str(tks[0].Value), line)
		expr := parserExprNode(t, lex.NewLine(line.Linenum, token), err, false, FuncInfo)
		if expr == nil {
			return nil
		}
		var buf strings.Builder
		generateTokenStr(&buf, tks...)
		return NewContinuityType(expr, typ, buf.String())
	} else if len(tks) == 2 && (tks[0].TYPE == lex.NAME || tks[0].TYPE == lex.LEA) && tks[1].TYPE == lex.TokenWithBrackets { //如果是 T[T1] 或&T[T1]这种泛型实例化
		return parserGenericInstantiation(t, tks, line, err, FuncInfo)
	}
	return nil
}

func lex_scan(t *Tree, s string, line *lex.Line) []lex.Token {
	scan := lex.NewScan(s, lex.ScanConfig{File: t.Filename, Errctx: t.errctx, Line: line.Linenum})
	return scan.AllScan()
}

func generateTokenStr(buf *strings.Builder, tks ...lex.Token) {
	for _, v := range tks {
		if v.TYPE == lex.MoreThanJustTokensWithBrackts {
			s := *v.PtrMoreThanJustTokensWithBracktsS().Ptr
			generateTokenStr(buf, s...)
		} else {
			buf.WriteString(v.Value)
		}
	}
}

// ret_middle_str 对于 [x] 返回 x
// 假设输入是一个前后为中括号的字符串
func ret_middle_str(s string) string {
	return s[1 : len(s)-1]
}

// parserTypeName 解析类型名
func parserTypeName(t *Tree, line *lex.Line, tk *lex.Token, err errcode.ErrCode, FuncInfo *FuncInfo) (typ astdata.Typ) {
	if tk.TYPE == lex.MoreThanJustTokensWithBrackts { //如果是连续类型
		typ = parserContinuityTypeOrGenericInstantiation(t, tk, line, err, FuncInfo)
		if typ == nil {
			t.Panic(line, nil, err, errcode.UnknownType)
			return nil
		}
		typ.SetTyp()
		return typ
	}
	//解析类型
	typ, ok := parserSelector(t, tk, line, FuncInfo)
	if !ok {
		kind := SymbolObj
		switch tk.TYPE {
		case lex.LEA:
			kind = LeaObj
		case lex.NAME:
		default: //如果既不是 T 也不是 &T
			t.Panic(line, nil, err, errcode.UnknownType)
			return nil
		}
		o := NewObject(kind, tk.Value)
		rewriteTypeName(t, &o.Name)
		typ = o
	}
	typ.SetTyp()
	return typ
}

// 解析函数
//
// 实现假定 line[0].Value[0].TYPE==FUNC
func parserFunc(t *Tree, line *lex.Line, FuncInfo *FuncInfo) *FuncNode {
	if FuncInfo != nil { //如果是在函数中声明函数
		t.Panic(line, nil, errcode.DeclFuncNoInFunc)
		return nil
	}
	if !check_lex_LBRACE(t, line, errcode.FUNCErr) { //语法规定位置没有左大括号
		return nil
	}
	funcinfo := check_func_decl(t, line, errcode.FUNCErr)
	if funcinfo == nil { //有错
		return nil
	}
	if t.PackageName != "" {
		for i := 0; i < len(funcinfo.Parame); i++ {
			funcinfo.Parame[i].Name = utils.GeneratePackageSymbol(t.PackageName, funcinfo.Parame[i].Name)
		}
	}
	if funcinfo.Name == "init" {
		t.IsInitFunc.Store(true)
		// init函数重命名为init__user
		funcinfo.Name = "init__user"
	}
	if t.PackageName != "" && funcinfo.Name != enum.Main {
		_, ok := Builtin_func_info[funcinfo.Name]
		if !ok { //如果不是内置函数
			funcinfo.Name = utils.GeneratePackageSymbol(t.PackageName, funcinfo.Name)
		}
	}
	if t.PackageName != "" && t.PackageName != enum.Main && funcinfo.Name == enum.Main { //如果非main包有main函数
		t.Panic(line, nil, errcode.NoMainPackageMustHaveNoMainFunc)
	}
	code := t.Sbt.AddFunc(funcinfo)
	if code != errcode.NoErr {
		t.Panic(line, errcode.NewMsgSymbol(funcinfo.Name), errcode.FUNCErr, code)
		return nil
	}
	ret := NewFuncNode(funcinfo) //返回函数节点
	ret.Sbt.seniorSbt(t.Sbt)
	for i := 0; i < len(funcinfo.Parame); i++ { //将每个参数视为局部变量，记录到符号表
		ret.Sbt.AddVar(funcinfo.Parame[i].Name, funcinfo.Parame[i].Type, true, line.Linenum, t.Filename)
	}
	return ret
}

//缩写: sentence缩写成 sece

// parserSece 解析语句
// 实现假定 line[0].Value[0].TYPE==NAME
func parserSece(t *Tree, line *lex.Line, InAutoFree bool, FuncInfo *FuncInfo) Node {
	if len(line.Value) < 2 { //如果只有一个符号
		t.Panic(line, nil, errcode.OPbug)
		return nil
	}
	switch line.Value[1].TYPE {
	case lex.ASSIGN: //是赋值
		return parserASSIGN(t, line, InAutoFree, FuncInfo)
	case lex.LPAREN: //有左小括号,如果前面是符号，视为函数调用
		if line.Value[0].TYPE != lex.NAME {
			break
		}
		c := parserCall(t, line, InAutoFree, FuncInfo)
		if c != nil {
			c.(*CallNode).nosemicolon = false
		}
		return c
	case lex.Colon: //是冒号，视为标签
		return parserLabel(t, line)
	case lex.Inc: //是自增语句
		ret := NewSelfOpStmt(enum.IncOP, parserObject(t, &line.Value[0], line, FuncInfo))
		return ret
	case lex.Dec: //是自增语句
		ret := NewSelfOpStmt(enum.DecOP, parserObject(t, &line.Value[0], line, FuncInfo))
		return ret
	}
	t.Panic(line, nil, errcode.OPbug)
	return nil
}

// 解析赋值表达式
//
// 对于不符合语法的赋值，返回nil
func parserASSIGN(t *Tree, line *lex.Line, InAutoFree bool, FuncInfo *FuncInfo) *ASSIGNNode {
	llen := len(line.Value)
	if llen == 3 { //是 dest = src
		dest := parserObject(t, &line.Value[0], line, FuncInfo)
		if dest == nil {
			return nil
		}
		src := parserObject(t, &line.Value[2], line, FuncInfo)
		if src == nil {
			return nil
		}
		ret := NewASSIGNNode(dest, src)
		return ret
	} else { //是 dest = expr expr=运算表达式
		exprstack := newstack(FuncInfo, InAutoFree)
		ret := exprstack.AutoExpr(t, line)
		exprstack.Close()
		return ret
	}
}

// parserObject 解析一个对象
//
// 如果是未知的变量，返回nil;不能解析的，panic
func parserObject(t *Tree, tk *lex.Token, line *lex.Line, FuncInfo *FuncInfo) Expr {
	var ret *Object
	switch tk.TYPE {
	case lex.NAME: //是符号
		selector, ok := parserSelector(t, tk, line, FuncInfo)
		if ok {
			return selector
		}
		ret = NewObject(SymbolObj, tk.Value)
	case lex.NUMBER: //是数字
		ret = NewObject(INTOBJ, tk.Value)
	case lex.FLOAT: //是浮点数
		ret = NewObject(FLOATOBJ, tk.Value)
	case lex.TRUE, lex.FALSE: //是布尔值
		ret = NewObject(BoolObj, tk.Value)
	case lex.String: //是字符串
		ret = NewObject(StringObj, tk.Value)
	case lex.LEA: //是取地址
		selector, ok := parserSelector(t, tk, line, FuncInfo)
		if selector != nil && ok {
			selector.Slice[0].Kind = LeaObj
			return selector
		}
		if selector == nil && ok {
			return nil
		}
		ret = NewObject(LeaObj, tk.Value[1:])
	case lex.Deref: //是解引用
		selector, ok := parserSelector(t, tk, line, FuncInfo)
		if ok {
			return selector
		}
		ret = NewObject(DerefObj, tk.Value[1:])
	case lex.Nil: //是指针的零值
		ret = NewObject(NilObj, tk.Value)
	case lex.MoreThanJustTokensWithBrackts:
		tks := *tk.PtrMoreThanJustTokensWithBracktsS().Ptr
		return parserIndexExpr(t, line, &tks[0], &tks[1], FuncInfo)
	default:
		panic(errutil.NewErr2(errutil.CompileErr, fmt.Sprintf("未知的类型 %+v", tk)))
	}
	return ret
}

// parserIndexExpr 解析索引表达式
func parserIndexExpr(t *Tree, line *lex.Line, x, exprt *lex.Token, FuncInfo *FuncInfo) *IndexExpr {
	var X, expr Expr
	if (x.TYPE == lex.NAME || x.TYPE == lex.MoreThanJustTokensWithBrackts) && exprt.TYPE == lex.TokenWithBrackets {
		X = parserObject(t, x, line, FuncInfo)
		if X == nil {
			return nil
		}
		token := lex_scan(t, ret_middle_str(exprt.Value), line)
		expr = parserExprNode(t, lex.NewLine(line.Linenum, token), errcode.NoErr, false, FuncInfo)
		if expr == nil {
			return nil
		}
		return NewIndexExpr(X, expr)
	}
	return nil
}

// parserSelector 解析选择器，如果不是选择器，返回nil,true
func parserSelector(t *Tree, tk *lex.Token, line *lex.Line, FuncInfo *FuncInfo) (*Objects, bool) {
	left := 0
	var ret *Objects
	for i := 0; i < len(tk.Value); i++ {
		switch tk.Value[i] {
		case '.':
			if ret == nil {
				ret = NewObjects(make([]*Object, 0, 2))
			}
			token := lex_scan(t, tk.Value[left:i], line)
			if len(token) == 0 {
				t.Panic(line, nil, errcode.LeftOrRightValueSelectorEmpty)
				return nil, true
			}
			if token[0].TYPE != lex.NAME && token[0].TYPE != lex.LEA && token[0].TYPE != lex.Deref {
				t.Panic(line, nil, errcode.SelectorLeftAndRightValueMustSymbol)
				return nil, true
			}
			ret.Slice = append(ret.Slice, parserObject(t, &token[0], line, FuncInfo).(*Object))
			left = i + 1
		}
	}
	if ret == nil {
		return nil, false
	}
	if left <= len(tk.Value) {
		token := lex_scan(t, tk.Value[left:], line)
		if len(token) == 0 {
			t.Panic(line, nil, errcode.LeftOrRightValueSelectorEmpty)
			return nil, true
		}
		if token[0].TYPE != lex.NAME && token[0].TYPE != lex.LEA && token[0].TYPE != lex.Deref {
			t.Panic(line, nil, errcode.SelectorLeftAndRightValueMustSymbol)
			return nil, true
		}
		ret.Slice = append(ret.Slice, parserObject(t, &token[0], line, FuncInfo).(*Object))
	}
	return ret, true
}

// 解析if
//
// 实现假定 line[0].Value[0].TYPE==IF
func parserIf(t *Tree, line *lex.Line, sbt *Sbt, InAutoFree bool, FuncInfo *FuncInfo) *IfNode {
	if !check_lex_LBRACE(t, line, errcode.IfErr) { //语法规定位置没有左大括号
		return nil
	}
	llen := len(line.Value)
	if llen == 2 { //有 if 和右大括号，就是没有名字
		t.Panic(line, nil, errcode.IfErr, errcode.NoBoolExpr)
		return nil
	}
	//创建 if节点
	ret := NewIfNode()
	ret.Sbt.seniorSbt(sbt)
	//解析布尔表达式
	if autoParserBoolExpr(t, *line, &ret.BoolExpr, "if", InAutoFree, FuncInfo) {
		return ret
	}
	return nil
}

// ParserExprNode 解析表达式节点
// - tree是抽象语法树, Tree.LVarTable Tree.Sbt 不能为空
// - line 是被解析的表达式
// - typ是如果出错的错误类型
// - IsAutoFree 是否在自动是否块内
func parserExprNode(t *Tree, line lex.Line, err errcode.ErrCode, InAutoFree bool, FuncInfo *FuncInfo) Expr {
	llen := len(line.Value)
	if llen == 1 { //不是表达式
		return parserObject(t, &line.Value[0], &line, FuncInfo)
	}
	stack := newstack(FuncInfo, InAutoFree) //获取表达式值
	stack.err = err
	return stack.AutoExprNode(t, &line)
}

// parserCodeBlock 解析代码块内的代码
//   - tree是抽象语法树, Tree.LVarTable Tree.Sbt 不能为空
//   - i 是调用者 [ParserNode] 的for循环中i的地址
//   - old是函数声明在lines的偏移量加1
//   - vlen是lines的长度
//   - wg是传递调用者 [ParserNode] 的wg参数
//   - lines是传递调用者 [ParserNode] 的lines参数
//   - ret是传递调用者 [ParserNode] 的ret参数
//   - Left是代码块节点的Left字段的地址
//   - Right是代码块节点的Right字段的地址
//   - Sbt是代码块节点的Sbt字段的地址
//   - check是传递调用者 [ParserNode] 的for循环中check的地址
//   - IsFunc是传递调用者 [ParserNode] 的IsFunc参数
func parserCodeBlock(tree *Tree, i *int, old, vlen int, lines []lex.Line, ret []Node, Left, Right *int, sbt *Sbt, check *braceStack, FuncInfo *FuncInfo, InAutoFree bool) {
	for *i < vlen-1 { //遍历lines
		*i++
		//如果左大括号和右大括号匹配
		if len(lines[*i].Value) != 0 && check.AutoAdd(lines[*i].Value) {
			ret[*i] = NewRbraceNode()
			//记录代码块内代码，第一个节点偏移量，结尾右大括号节点偏移量
			*Left = old
			*Right = *i
			// 实际解析解析代码块内的代码
			ParserNode(tree, lines, sbt, ParserNodeState{Index: old, End: *i, Ret: ret, FuncInfo: FuncInfo, IsRecursion: true, InAutoFree: InAutoFree})
			break
		}
	}
}

// autoCodeBlock 解析代码块节点和代码块内的代码
//   - tree是抽象语法树, Tree.LVarTable Tree.Sbt 不能为空
//   - typ是生成的代码块类型
//   - i 是调用者 [ParserNode] 的for循环中i的地址
//   - vlen是lines的长度
//   - wg是传递调用者 [ParserNode] 的wg参数
//   - lines是传递调用者 [ParserNode] 的lines参数
//   - ret是传递调用者 [ParserNode] 的ret参数
//   - sbt是传递调用者 [ParserNode] 的sbt参数
//   - IsFunc是被解析的部分否在函数内
func autoCodeBlock(tree *Tree, typ string, i *int, vlen int, lines []lex.Line, ret []Node, sbt *Sbt, FuncInfo *FuncInfo, InAutoFree bool) {
	var node codeBlockIface
	old := *i
	switch typ {
	case enum.Func: //是函数
		f := parserFunc(tree, &lines[*i], FuncInfo)
		if f == nil {
			return
		}
		tree.CHeaderFile.Add(CHeaderFile{f, lines[old].Linenum})
		FuncInfo, node = f.FuncInfo, f
	case "if": //是if
		node = parserIf(tree, &lines[*i], sbt, InAutoFree, FuncInfo)
	case "else": //是else
		node = parserElse(tree, &lines[*i], sbt, InAutoFree, FuncInfo)
	case "for": //是for
		node = parserFor(tree, &lines[*i], sbt, FuncInfo, InAutoFree)
	case enum.Switch: //是switch
		node = parserSwitch(tree, &lines[*i], sbt, InAutoFree, FuncInfo)
	case enum.Method: //是方法
		f := parserMethod(tree, &lines[*i], FuncInfo)
		if f == nil {
			return
		}
		tree.CHeaderFile.Add(CHeaderFile{f, lines[old].Linenum})
		FuncInfo, node = f.FuncInfo, f
	case enum.AutoFree: //是自动释放块
		node = parserAutoFree(tree, &lines[*i], sbt, InAutoFree, FuncInfo)
		InAutoFree = true
	}
	if utils.IsNil(node) {
		//没有成功生成代码块节点(接口值为nil说明typ不是已知的)
		return
	}
	ret[*i] = node
	check := newbraceStack(1)
	//解析代码块内的代码
	parserCodeBlock(tree, i, *i+1, vlen, lines, ret, node.getLeft(), node.getRight(), node.getSbt(), &check, FuncInfo, InAutoFree)
	if !check.Ok() { //缺失右大括号
		tree.Panic(&lines[*i], errcode.NewMsgBracesNoEqual(check.leftNum, check.rightNum), codeBlock_errmap[typ], errcode.EmptyRbrace)
	} else {
		if typ == enum.AutoFree {
			mempool := NewObject(LeaObj, utils.Generate_mempool_Name(old+1, tree.Filename))
			c := NewCallExpr(NewObject(SymbolObj, enum.MemPoolFree), true, mempool)
			c.nosemicolon = false
			ret[*i] = c
			try_AutoFreeIn(old, *i, ret, mempool)
		}
	}
}

// 解析else
//
// 实现假定 line[0].Value[0].TYPE==ELSE
func parserElse(t *Tree, line *lex.Line, sbt *Sbt, InAutoFree bool, FuncInfo *FuncInfo) *ElseNode {
	ok := check_lex_LBRACE(t, line, errcode.ElseErr)
	if !ok { //语法规定位置没有左大括号
		return nil
	}
	//创建 else节点
	ret := NewElseNode()
	ret.Sbt.seniorSbt(sbt)
	llen := len(line.Value)
	if llen == 2 { //如果是 else {
		return ret
	}
	if autoParserBoolExpr(t, *line, &ret.BoolExpr, "else", InAutoFree, FuncInfo) { //如果是 else if boolexpr {
		return ret
	}
	return nil
}

// autoParserBoolExpr 解析 if或else if 或for的布尔表达式
func autoParserBoolExpr(t *Tree, line lex.Line, BoolExpr *Expr, typ string, InAutoFree bool, FuncInfo *FuncInfo) bool {
	var exprline []lex.Token
	switch typ {
	case "if": //如果是if,表达式在关键字if后
		exprline = line.Value[1:]
	case "else": //如果是else if,表达式在关键字else if后
		exprline = line.Value[2:]
	case "for": //如果是for,表达式是输入全部
		exprline = line.Value
	}
	if typ != "for" {
		//有左大括号排除在表达式外
		exprline = exprline[:len(exprline)-1]
	}
	boolexpr := parserExprNode(t, lex.NewLine(line.Linenum, exprline), codeBlock_errmap[typ], InAutoFree, FuncInfo)
	if utils.IsNil(boolexpr) { //值为nil,表示生成布尔表达式失败
		return false
	}
	*BoolExpr = boolexpr
	if t.PackageName != "" {
		overwrite_ident_node(t, boolexpr)
	}
	return true
}

// 解析for
//
// 实现假定 line[0].Value[0].TYPE==FOR
func parserFor(t *Tree, line *lex.Line, sbt *Sbt, FuncInfo *FuncInfo, InAutoFree bool) *ForNode {
	ok := check_lex_LBRACE(t, line, errcode.ForErr)
	if !ok { //语法规定位置没有左大括号
		return nil
	}
	llen := len(line.Value)
	if llen == 2 { //只有 for 和右大括号
		t.Panic(line, errcode.NewMsgNumberOfSemicolons(0), errcode.ForErr)
		return nil
	}
	retstr, num := splitFor(line)
	if num != 2 { //如果分号的数量不是2
		t.Panic(line, errcode.NewMsgNumberOfSemicolons(num), errcode.ForErr)
		return nil
	}
	// for语句确定是for initstmt;boolexpr;endstmt {
	ret := NewForNode() //创建 for节点
	ret.Sbt.seniorSbt(sbt)
	//解析初始化语句
	if len(retstr[0].Value) != 0 { //初始化语句非空
		initstmt := ParserNode(t, []lex.Line{retstr[0]}, ret.Sbt, ParserNodeState{Index: 0, End: 0, Ret: nil, FuncInfo: FuncInfo, IsRecursion: true, InAutoFree: InAutoFree})
		ret.InitStmt = initstmt[0]
		overwrite_ident_node(t, ret.InitStmt)
	}
	//解析结束语句
	if len(retstr[2].Value) != 0 { //结束语句非空
		endstmt := ParserNode(t, []lex.Line{retstr[2]}, ret.Sbt, ParserNodeState{Index: 0, End: 0, Ret: nil, FuncInfo: FuncInfo, IsRecursion: true, InAutoFree: InAutoFree})
		ret.EndStmt = endstmt[0]
		overwrite_ident_node(t, ret.EndStmt)
	}
	//解析布尔表达式
	if len(retstr[1].Value) != 0 { //布尔表达式非空
		autoParserBoolExpr(t, retstr[1], &ret.BoolExpr, "for", InAutoFree, FuncInfo)
	}
	return ret
}

// splitFor 将for语句按分号分割，返回被for和分号，以及分号和分号，以及末尾分隔的字符串
//
//	例如对于 for var i int=0 ; i<3 ; i=i+1 {
//		将返回的值等价于 Lex("",1,[]string{"var i int = 0 ","i < 3 ","i = i + 1"},nil)
func splitFor(line *lex.Line) ([]lex.Line, int) {
	SEMICOLONnum := 0
	old := 1
	ret := make([]lex.Line, 0, 3)
	llen := len(line.Value) - 1
	for i := 1; i < llen; i++ { //对于for initstmt;boolexpr;endstmt [{],从1开始遍历词法分析结果
		if line.Value[i].TYPE == lex.SEMICOLON { //如果发现分号
			// 将最后未遍历和分号之间的词法分析结果用空格连接
			var buf = make([]lex.Token, 0, i-old)
			for index := old; index < i; index++ {
				buf = append(buf, line.Value[index])
			}
			ret = append(ret, lex.NewLine(line.Linenum, buf))
			SEMICOLONnum++ //分号计数加1
			old = i + 1    //更新最后未遍历的偏移量
		}
	}
	// 将最后未遍历和分号之间的词法分析结果用空格连接
	var buf = make([]lex.Token, 0, llen-old)
	for index := old; index < llen; index++ {
		buf = append(buf, line.Value[index])
	}
	ret = append(ret, lex.NewLine(line.Linenum, buf))
	return ret, SEMICOLONnum
}

// parserCall 解析函数调用或语法形式相同的解引用表达式
// 实现假定如果是函数调用函数调用 line.Value[0].TYPE==NAME
func parserCall(t *Tree, line *lex.Line, InAutoFree bool, FuncInfo *FuncInfo) Expr {
	if line.Value[0].Value == "@" { //如果是解引用表达式
		nline := lex.NewLine(line.Linenum, line.Value[1:])
		n := parserExprNode(t, nline, errcode.NoErr, InAutoFree, FuncInfo)
		if n == nil {
			return nil
		}
		return &Dereference{Value: n}
	}
	builtin := false
	switch line.Value[0].Value { //检查是否是禁止调用的函数
	case "main":
		t.Panic(line, nil, errcode.ProhibitCallMainFunc)
		return nil
	case "init":
		t.Panic(line, nil, errcode.ProhibitCallInitFunc)
		return nil
	}
	_, builtin = Builtin_func_info[line.Value[0].Value]
	if InAutoFree && !builtin {
		line.Value[0].Value = line.Value[0].Value + enum.AutoFreeInFunc
	}
	var funcname FuncNameNode
	if line.Value[0].TYPE == lex.MoreThanJustTokensWithBrackts {
		g := parserGenericInstantiation(t, *line.Value[0].PtrMoreThanJustTokensWithBracktsS().Ptr, line, errcode.CallErr, FuncInfo) //记录泛型实例化
		if FuncInfo == nil {
			t.GenericTable.AddGenInst(g)
		}
		if FuncInfo != nil && !isUseType(g.ActualType, FuncInfo.TypeParame) {
			t.GenericTable.AddGenInst(g)
		}
		funcname = g
	} else {
		funcname = parserObject(t, &line.Value[0], line, FuncInfo).(FuncNameNode)
	}
	ret := NewCallExpr(funcname, InAutoFree)
	s := newstack(FuncInfo, InAutoFree)
	ret.Parame = s.AutoParameList(t, line)
	s.Close()
	for i := 0; i < len(ret.Parame); i++ {
		overwrite_ident_node(t, ret.Parame[i])
	}
	return ret
}

// parserReturn 解析返回语句
// 实现假定 line.Value[0].TYPE==Return
func parserReturn(t *Tree, line *lex.Line, InAutoFree bool, FuncInfo *FuncInfo) *ReturnNode {
	ret := NewReturnNode()
	ret.RetValue = parserReturnValue(t, line, InAutoFree, FuncInfo)
	overwrite_ident_node(t, ret.RetValue)
	return ret
}

// parserReturnValue 解析返回值
// 实现假定 line.Value[0].TYPE==Return
func parserReturnValue(t *Tree, line *lex.Line, InAutoFree bool, FuncInfo *FuncInfo) Expr {
	if len(line.Value) == 1 { //如果没有返回值
		return nil
	}
	l := *line
	l.Value = l.Value[1:]
	return parserExprNode(t, l, errcode.ReturnErr, InAutoFree, FuncInfo)
}

// parserGoto 解析goto语句
// 实现假定 line.Value[0].TYPE==GOTO
func parserGoto(t *Tree, line *lex.Line) *GotoStmt {
	llen := len(line.Value)
	if llen != 2 {
		if llen < 2 { //小于2说明只有goto关键字，没有标签
			t.Panic(line, nil, errcode.GotoErr, errcode.NoLabel)
		} else { //又不等于2又不小于2，就是大于2
			t.Panic(line, nil, errcode.GotoErr, errcode.OPbug)
		}
		return nil
	}
	if line.Value[1].TYPE != lex.NAME { //标签应该被词法分析识别为符号，如果不是
		t.Panic(line, nil, errcode.GotoErr, errcode.NoLabel)
		return nil
	}
	ret := NewGotoStmt(line.Value[1].Value)
	return ret
}

// parserLabel 解析标签
// 实现假定 line.Value[1].TYPE==Colon
func parserLabel(t *Tree, line *lex.Line) *LabelNode {
	llen := len(line.Value)
	if llen > 2 { //一个标签的词法分析应该只分析出两个单词 从左到右是符号 冒号
		t.Panic(line, nil, errcode.LabelErr, errcode.OPbug)
		return nil
	}
	if line.Value[0].TYPE != lex.NAME { //一个标签的词法分析应该只分析出两个单词 从左到右是符号 冒号
		t.Panic(line, nil, errcode.LabelErr, errcode.NoName)
		return nil
	}
	return NewLabelNode(line.Value[0].Value)
}

// parserBreak 解析break
// 实现假定 line.Value[0].TYPE==Break
func parserBreak(t *Tree, line *lex.Line) BreakStmt {
	llen := len(line.Value)
	if llen > 1 { //break语句一行应该只有一个break
		t.Panic(line, nil, errcode.BreakErr, errcode.OPbug)
	}
	return NewBreakStmt()
}

// parserContinue 解析continue
// 实现假定 line.Value[0].TYPE==Continue
func parserContinue(t *Tree, line *lex.Line) ContinueStmt {
	llen := len(line.Value)
	if llen > 1 { //continue语句一行应该只有一个continue
		t.Panic(line, nil, errcode.ContinueErr, errcode.OPbug)
	}
	return NewContinueStmt()
}

// 解析常量
// 实现假定 line.Value[0].TYPE==Const
func parserConst(t *Tree, line *lex.Line, sbt *Sbt, InAutoFree bool, FuncInfo *FuncInfo) *ConstNode {
	llen := len(line.Value)
	if llen < 2 { //只有常量标识符
		t.Panic(line, nil, errcode.ConstErr, errcode.NoName)
		return nil
	}
	if llen == 2 { //没有类型
		t.Panic(line, nil, errcode.ConstErr, errcode.NoType)
		return nil
	}
	if llen == 3 { //常量没有初始化
		t.Panic(line, nil, errcode.ConstErr, errcode.NoConstInit)
		return nil
	}
	if llen >= 5 && line.Value[1].TYPE == lex.NAME && line.Value[2].TYPE == lex.NAME && line.Value[3].TYPE == lex.ASSIGN { //声明并初始化常量
		ret := checkConstNameAndType(t, line, line.Value[1].Value, &line.Value[2], sbt, FuncInfo)
		if ret == nil {
			return nil
		}
		// dest =(*line).Value[1]
		// src =(*line).Value[3:]
		expr := lex.NewLine(line.Linenum, append(append([]lex.Token(nil), (*line).Value[1]), (*line).Value[3:]...))
		asnode := parserASSIGN(t, &expr, InAutoFree, FuncInfo) //解析赋值
		if asnode == nil {                                     //如果初始化赋值不符合语法
			return nil
		}
		overwrite_ident_node(t, asnode)
		ret.Value = asnode.Src //常量节点记录源操作数
		return ret
	}
	//无法识别
	t.Panic(line, nil, errcode.ConstErr, errcode.OPbug)
	return nil
}

func isName(typ lex.TokenType) bool {
	return typ == lex.NAME || typ == lex.MoreThanJustTokensWithBrackts
}

// parserName 解析可能带类型参数的名字
func parserName(t *Tree, tk *lex.Token, line *lex.Line, err errcode.ErrCode, FuncInfo *FuncInfo) (name string, Typeparame []astdata.NameAndType, ok bool) {
	if tk.TYPE == lex.NAME {
		name, ok = tk.Value, true
	} else { //如果使用了
		Typeparame, name = check_TypeParame(t, tk, line, err, FuncInfo)
		if len(Typeparame) == 0 || len(name) == 0 { //如果类型参数列表和符号名称至少一个获取失败
			return "", nil, false
		}
		ok = true
	}
	return
}

// parserStruct 解析结构体
// 实现假定 line.Value[0].TYPE==Struct
func parserStruct(t *Tree, i *int, lines []lex.Line, sbt *Sbt, FuncInfo *FuncInfo) *StructDecl {
	ok := check_lex_LBRACE(t, &lines[*i], errcode.StructErr)
	if !ok { //语法规定位置没有左大括号
		return nil
	}
	llen := len(lines[*i].Value)
	if llen != 3 { //如果不是 struct name {
		if llen == 2 { //既有struct 又有{ 就是没有名
			t.Panic(&lines[*i], nil, errcode.StructErr, errcode.NoName)
		} else {
			t.Panic(&lines[*i], nil, errcode.StructErr, errcode.OPbug)
		}
		return nil
	}
	var ret = new(StructDecl)
	ret.Name, ret.TypeParame, ok = parserName(t, &lines[*i].Value[1], &lines[*i], errcode.StructErr, FuncInfo)
	if !ok {
		return nil
	}
	ret.LineNum, ret.sbt, ret.FileName, ret.InFunc = lines[*i].Linenum, sbt, t.Filename, FuncInfo != nil
	start := *i + 1
	end := rbraceIndex(i, lines) //如果和start合并在一行，测试会失败，所以写两行
	if end == 0 {
		t.Panic(&lines[*i], nil, errcode.StructErr, errcode.EmptyRbrace)
		return nil
	}
	ret.FieldTable = check_struct_field(t, lines[start:end], FuncInfo) //解析所有字段
	ret.Name = utils.GeneratePackageSymbol(t.PackageName, ret.Name)
	code := sbt.AddStruct(ret.Name, ret)
	if code != errcode.NoErr { //符号表记录结构体如果重名
		t.Panic(&lines[start-1], errcode.NewMsgSymbol(ret.Name), errcode.StructErr, code)
	}
	return ret
}

// parser_package 解析包声明
// 实现假定 line.Value[0].TYPE==Package
func parser_package(t *Tree, line *lex.Line) {
	if len(line.Value) == 1 { //如果只有package
		t.Panic(line, nil, errcode.PackageDeclMustName)
		return
	}
	if len(line.Value) > 2 { //如果不止package name
		t.Panic(line, nil, errcode.PackageDeclOnlyName)
		return
	}
	if line.Value[1].Value == "unsafe" { //如果包名等于 unsafe
		t.Panic(line, nil, errcode.PackageNameCannotBeEqualUnsafe)
		return
	}
	if line.Linenum != 1 { //如果不是在第一行
		t.Panic(line, nil, errcode.PackageDeclMustFirstLine)
		return
	}
	t.PackageName = line.Value[1].Value
}

// 解析switch 语句
//
// 实现假定 line[0].Value[0].TYPE==Switch
func parserSwitch(t *Tree, line *lex.Line, sbt *Sbt, InAutoFree bool, FuncInfo *FuncInfo) *SwitchNode {
	if !check_lex_LBRACE(t, line, errcode.SwitchErr) { //语法规定位置没有左大括号
		return nil
	}
	llen := len(line.Value)
	if llen == 2 { //只有 switch 和 { 就是没有表达式
		t.Panic(line, nil, errcode.SwitchErr, errcode.NoExpr)
		return nil
	}
	//创建 switch节点
	ret := NewSwitchNode()
	ret.Sbt.seniorSbt(sbt)
	ret.Expr = parserExprNode(t, lex.NewLine(line.Linenum, line.Value[1:len(line.Value)-1]), errcode.SwitchErr, InAutoFree, FuncInfo)
	overwrite_ident_node(t, ret.Expr)
	return ret
}

// 解析case 语句
//
// 实现假定 line[0].Value[0].TYPE==Case
func parserCase(t *Tree, line *lex.Line, sbt *Sbt, InAutoFree bool, FuncInfo *FuncInfo) *CaseNode {
	llen := len(line.Value)
	if llen < 3 { //正确的 case 语句 case expr : 至少三个token
		if line.Value[llen-1].TYPE != lex.Colon { //如果末尾不是冒号
			t.Panic(line, nil, errcode.CaseErr, errcode.ExpectColonAtEnd)
		} else {
			t.Panic(line, nil, errcode.CaseErr, errcode.NoExpr)
		}
		return nil
	}
	ret := NewCaseNode()
	ret.Sbt.seniorSbt(sbt)
	ret.Expr = parserExprNode(t, lex.NewLine(line.Linenum, line.Value[1:llen-1]), errcode.CaseErr, InAutoFree, FuncInfo)
	overwrite_ident_node(t, ret.Expr)
	return ret
}

// parserCaseOrDefaultBlock 解析case或default的代码块
func parserCaseOrDefaultBlock(tree *Tree, lines []lex.Line, i *int, old int, vlen int, sbt *Sbt, err errcode.ErrCode, state ParserNodeState) {
	check := newbraceStack(1) //Note:设置左大括号为1是为了在，按语法只有一个右大括号时可以check.Ok()==true，以及case或default中有右大括号时，能不把右大括号的位置可能不正确的视为代码块的范围
CheckMatch:
	for *i < vlen-1 { //遍历lines后边的
		*i++
		if len(lines[*i].Value) != 0 {
			switch lines[*i].Value[0].TYPE { //如果开头是case或default
			case lex.Case, lex.Default:
				break CheckMatch
			}
			switch lines[*i].Value[len(lines[*i].Value)-1].TYPE { //如果结束是左大括号或右大括号
			case lex.LBRACE:
				check.leftNum++
			case lex.RBRACE:
				check.rightNum++
				if check.Ok() { //左右括号匹配或只有一个右大括号（在switch最后的case或default只会发现一个右大括号）
					break CheckMatch
				}
			default:
				continue CheckMatch
			}
		}
	}
	if !check.Ok() && check.leftNum != 1 { //如果左右大括号数量不匹配
		//Note:check.leftNum-1时因为左大括号多算了1个
		tree.Panic(&lines[old], errcode.NewMsgBracesNoEqual(check.leftNum-1, check.rightNum), err)
		return
	}
	ParserNode(tree, lines, sbt, ParserNodeState{Index: old + 1, End: *i, Ret: state.Ret, FuncInfo: state.FuncInfo, IsRecursion: true, InAutoFree: state.InAutoFree})
}

// 解析default 语句
//
// 实现假定 line[0].Value[0].TYPE==Default
func parserDefault(t *Tree, line *lex.Line, sbt *Sbt) *DefaultNode {
	llen := len(line.Value)
	if llen != 2 { //正确的 default 语句 default : 两个token
		if llen == 1 { //如果末尾不是冒号
			t.Panic(line, nil, errcode.DefaultErr, errcode.ExpectColonAtEnd)
		} else {
			t.Panic(line, nil, errcode.DefaultErr, errcode.OPbug)
		}
		return nil
	}
	ret := NewDefaultNode()
	ret.Sbt.seniorSbt(sbt)
	return ret
}

// 解析方法
//
// 实现假定 line[0].Value[0].TYPE==Method
func parserMethod(t *Tree, line *lex.Line, FuncInfo *FuncInfo) *MethodNode {
	if FuncInfo != nil { //如果是在函数中声明方法,方法相当于函数
		t.Panic(line, nil, errcode.DeclMethodInFunc)
		return nil
	}
	if !check_lex_LBRACE(t, line, errcode.MethodErr) { //语法规定位置没有左大括号
		return nil
	}
	funcinfo := check_func_decl(t, line, errcode.MethodErr)
	if funcinfo == nil { //有错
		return nil
	}
	if len(funcinfo.Parame) == 0 { //如果方法的第一个参数类型不是自定义类型
		t.Panic(line, nil, errcode.MethodErr, errcode.FirstParameTypeOfMethodACustomType)
		return nil
	}
	var typ string
	if g, ok := funcinfo.Parame[0].Type.(*GenericInstantiation); ok {
		typ = g.BaseName.Typ()
	} else {
		typ = funcinfo.Parame[0].Type.Typ()
	}
	typ = utils.Ret_no_lea(typ)
	_, isnoCustomType := TypeEnumStrMap[typ]
	if isnoCustomType { //如果方法的第一个参数类型不是自定义类型
		t.Panic(line, nil, errcode.MethodErr, errcode.FirstParameTypeOfMethodACustomType)
		return nil
	}
	//重写字段名
	for i := 0; i < len(funcinfo.Parame); i++ {
		funcinfo.Parame[i].Name = utils.GeneratePackageSymbol(t.PackageName, funcinfo.Parame[i].Name)
	}
	ret := NewMethodNode(typ, funcinfo) //返回方法节点
	code := t.Sbt.AddMethod(typ, ret)
	if code != errcode.NoErr {
		t.Panic(line, nil, errcode.MethodErr, code)
		return nil
	}
	ret.Sbt.seniorSbt(t.Sbt)
	for i := 0; i < len(funcinfo.Parame); i++ { //将每个参数视为局部变量，记录到符号表
		ret.Sbt.AddVar(funcinfo.Parame[i].Name, funcinfo.Parame[i].Type, true, line.Linenum, t.Filename)
	}
	return ret
}

// 解析import语句
//
// 实现假定 line[0].Value[0].TYPE==Import
func parserImport(t *Tree, lines []lex.Line, i *int, FuncInfo *FuncInfo) {
	if FuncInfo != nil { //如果在函数内
		t.Panic(&lines[*i], nil, errcode.ImportErr, errcode.ImportShouldBeOutSideOfTheFunc)
		return
	}
	if !check_lex_LBRACE(t, &lines[*i], errcode.ImportErr) { //语法规定位置没有左大括号
		return
	}
	if len(lines[*i].Value) != 2 { //如果不是 import {
		t.Panic(&lines[*i], nil, errcode.ImportErr, errcode.OPbug)
		return
	}
	old := *i + 1
	end := rbraceIndex(i, lines)
	if end == 0 { //如果没找到右大括号
		t.Panic(&lines[*i], nil, errcode.ImportErr, errcode.EmptyRbrace)
		return
	}
	for ; old < end; old++ {
		if len(lines[old].Value) == 0 { //如果是空行
			continue
		}
		if lines[old].Value[0].TYPE != lex.String { //如果导入路径不是字符串
			t.Panic(&lines[old], nil, errcode.ImportErr, errcode.ImportPathMustString)
			continue
		}
		basename := clean_path(lines[old].Value[0].Value)
		t.ImportTable.add(basename, enum.SymbolImport, ImportInfo{Path: ret_string_value(lines[old].Value[0].Value)})
		t.Sbt.add(basename, enum.SymbolImport, ImportInfo{Path: ret_string_value(lines[old].Value[0].Value)})
	}
}

func ret_string_value(s string) string {
	return s[1 : len(s)-1]
}

func clean_path(s string) string {
	s = filepath.Base(s)
	s = s[:len(s)-1]
	return s
}

// parserEnum 解析枚举
// 实现假定 line.Value[0].TYPE==Enum
func parserEnum(t *Tree, i *int, lines []lex.Line, sbt *Sbt) *EnumDecl {
	ok := check_lex_LBRACE(t, &lines[*i], errcode.EnumErr)
	if !ok { //语法规定位置没有左大括号
		return nil
	}
	llen := len(lines[*i].Value)
	if llen != 3 { //如果不是 enum name {
		if llen == 2 { //如果既有enum又有 { 就是没有名字
			t.Panic(&lines[*i], nil, errcode.EnumErr, errcode.NoName)
		} else {
			t.Panic(&lines[*i], nil, errcode.EnumErr, errcode.OPbug)
		}
		return nil
	}
	ret, start := NewEnumDecl(lines[*i].Value[1].Value), *i+1
	end := rbraceIndex(i, lines)
	if end == 0 {
		t.Panic(&lines[*i], nil, errcode.EnumErr, errcode.EmptyRbrace)
		return nil
	}
	ret.Enums = check_enums(t, lines[start:end]) //解析所有字段
	if len(ret.Enums) == 0 {                     //如果是空枚举
		t.Panic(&lines[*i], nil, errcode.EnumErr, errcode.EmptyEnum)
		return nil
	}
	for i := 0; i < len(ret.Enums); i++ { //重写标识符
		var buf strings.Builder
		buf.WriteString(t.PackageName)
		buf.WriteString(enum.PackageSep)
		buf.WriteString(ret.Name)
		buf.WriteString(enum.PackageSep)
		buf.WriteString(ret.Enums[i])
		ret.Enums[i] = buf.String()
	}
	ret.Name = utils.GeneratePackageSymbol(t.PackageName, ret.Name)
	code := sbt.AddEnum(ret)
	if code != errcode.NoErr { //符号表记录结构体，如果重名
		t.Panic(&lines[start-1], errcode.NewMsgSymbol(ret.Name), errcode.EnumErr, code)
	}
	return ret
}

// rbraceIndex 获取右大括号所在的下标
func rbraceIndex(i *int, lines []lex.Line) int {
	vlen := len(lines)
	for *i < vlen-1 { //遍历lines
		*i++
		//如果发现右大括号
		if len(lines[*i].Value) != 0 && lines[*i].Value[0].TYPE == lex.RBRACE {
			return *i
		}
	}
	return 0
}
